﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Qiang.Geometry
{
    public abstract class Geometry : IGeometry
    {

        #region 初始化

        /// <summary>
        /// 
        /// </summary>
        /// <param name="type"></param>
        public Geometry()
        {

        }

        #endregion


        #region 属性


        /// <summary>
        /// 图形类型
        /// </summary>
        public abstract GeometryType GeometryType { get; }

        /// <summary>
        /// 坐标集合
        /// </summary>
        public abstract IList<Coordinate> Coordinates { get; set; }

        /// <summary>
        /// 是否为空。
        /// </summary>
        public abstract bool IsEmpty { get; }

        /// <summary>
        /// 是否为简单几何图形。
        /// 简单几何图形：不存在自相切、自相交。
        /// </summary>
        public abstract bool IsSimple { get; }

        /// <summary>
        /// 
        /// </summary>
        public abstract int Dimension { get; }

        /// <summary>
        /// 
        /// </summary>
        public int Srid
        {
            get;
            set;
        }


        /// <summary>
        /// 图形范围
        /// </summary>
        public IEnvelope Envelope
        {
            get
            {
                return ComputeEnvelope();
            }
        }


        #endregion


        #region  内部方法

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        IEnvelope ComputeEnvelope()
        {
            List<Coordinate> CoordinateLst = new List<Coordinate>();
            CoordinateLst.AddRange(Coordinates);
            if (CoordinateLst.Count == 0) return new Envelope();

            double minX = CoordinateLst[0].X;
            double minY = CoordinateLst[0].Y;
            double maxX = CoordinateLst[0].X;
            double maxY = CoordinateLst[0].Y;
            foreach (Coordinate coor in CoordinateLst)
            {
                minX = Math.Min(minX, coor.X);
                minY = Math.Min(minY, coor.Y);
                maxX = Math.Max(maxX, coor.X);
                maxY = Math.Max(maxY, coor.Y);
            }
            return new Envelope(minX, minY, maxX, maxY);
        }

        #endregion


        #region 查询方法

        /// <summary>
        /// 在空间上，两个图形是否相等。
        /// </summary>
        /// <param name="Geometry"></param>
        /// <returns></returns>
        public virtual bool Equals(IGeometry Geometry)
        {
            return false;
        }

        /// <summary>
        /// 在空间上，两个图形是否相等。
        /// </summary>
        /// <param name="Geometry"></param>
        /// <returns></returns>
        public virtual bool Disjoint(IGeometry Geometry)
        {
            return false;
        }

        /// <summary>
        /// 在空间上，两个图形是否相交。
        /// </summary>
        /// <param name="?"></param>
        /// <returns></returns>
        public virtual bool Intersects(IGeometry Geometry)
        {
            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Geometry"></param>
        /// <returns></returns>
        public virtual bool Intersects(IEnvelope Envelope)
        {
            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Geometry"></param>
        /// <returns></returns>
        public virtual bool Touches(IGeometry Geometry)
        {
            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Geometry"></param>
        /// <returns></returns>
        public virtual bool Crosses(IGeometry Geometry)
        {
            return false;
        }

        /// <summary>
        /// 在空间上，此图形是否在参数图形之内。
        /// </summary>
        /// <param name="Geometry"></param>
        /// <returns></returns>
        public virtual bool Within(IGeometry Geometry)
        {
            return false;
        }

        /// <summary>
        /// 在空间上，此图形是否包含参数图形。
        /// </summary>
        /// <param name="Geometry"></param>
        /// <returns></returns>
        public virtual bool Contains(IGeometry Geometry)
        {
            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Geometry"></param>
        /// <returns></returns>
        public virtual bool Overlaps(IGeometry Geometry)
        {
            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Geometry"></param>
        /// <returns></returns>
        public virtual bool Relate(IGeometry Geometry)
        {
            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="M"></param>
        /// <returns></returns>
        public virtual IGeometry LocateAlong(double M)
        {
            return null;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="startM"></param>
        /// <param name="endM"></param>
        /// <returns></returns>
        public virtual IGeometry LocateBetween(double startM, double endM)
        {
            return null;
        }


        #endregion


        #region 分析方法

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Geometry"></param>
        /// <returns></returns>
        public virtual double Distance(IGeometry Geometry)
        {
            return 0;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="distance"></param>
        /// <returns></returns>
        public virtual IGeometry Buffer(double distance)
        {
            return null;
        }

        /// <summary>
        /// 此图形的凸包。
        /// </summary>
        /// <returns></returns>
        public virtual IGeometry ConvexHull()
        {
            return null;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Geometry"></param>
        /// <returns></returns>
        public virtual IGeometry Intersection(IGeometry Geometry)
        {
            return null;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Geometry"></param>
        /// <returns></returns>
        public virtual IGeometry Union(IGeometry Geometry)
        {
            return null;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Geometry"></param>
        /// <returns></returns>
        public virtual IGeometry Diffrence(IGeometry Geometry)
        {
            return null;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Geometry"></param>
        /// <returns></returns>
        public virtual IGeometry SymDifference(IGeometry Geometry)
        {
            return null;
        }


        #endregion


        #region SQL


        /// <summary>
        /// 获取WKT描述.
        /// </summary>
        /// <returns></returns>
        public abstract string AsText();

        /// <summary>
        /// 获取WKB描述.
        /// </summary>
        /// <returns></returns>
        public abstract byte[] AsBinarry();


        #endregion



        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return base.ToString();
        }



    }
}
